/**
 * A FilterAgent acts like a FilterLayer, except that FilterAgent does not actually draws the filters. Actually, FilterAgent is not a DisplayObject,
 * but rather an array collection of filters. This class is used extensively in GraphicBorderSkin classes, because these skins are drawn using Degrafa,
 * on whown a FilterLayer cannot be added.
 * 
 * @since Indy2 1.1
 */ 
package org.delphy.indy2.layers
{
	import flash.filters.BitmapFilter;
	
	import mx.skins.Border;
	import mx.styles.CSSStyleDeclaration;
	import mx.styles.StyleManager;
	
	import org.delphy.indy2.core.ICarbonComponent;
	
	public class FilterFactory
	{	
		/**
		 * @public
		 * 
		 * Why we do not pass a "host" as parameter?
		 * Because programmatic skin using Degrafa is not a UIComponent, so what we do is to pass a styleName instead.
		 * In this way, we avoid complex checking process on exactly what kind of a class the "host" is
		 */	
		public static function createFilters(host:*, layerName:String="filterLayer"):Array{
			var filterStack:Array;
			var filterObject:Object;
			if(host.getStyle(layerName))
				filterObject=host.getStyle(layerName);
			else{
				var defaultStyle:String;
				if(host is Border)
					defaultStyle = "." + ICarbonComponent(host.styleName).defaultStyleName;
				else
					defaultStyle = "." + ICarbonComponent(host).defaultStyleName;
				filterObject = StyleManager.getStyleDeclaration(defaultStyle).getStyle(layerName);
			}
			
			// Cast the filter objects to an array
			if(filterObject is String)
				filterStack=[filterObject];
			else
				filterStack=filterObject as Array;
			
			if(filterStack.length==0)
				return new Array();
			
			var filterArray:Array=[];
			for each(var filterStyleName:String in filterStack){
				// In case users forgot to put "." as a CSS class prefix, we are offering a adjustment here
				if(filterStyleName.charAt(0)!=".")
					filterStyleName="." + filterStyleName;
				
				var filter:BitmapFilter=parseFilter(filterStyleName);
				filterArray.push(filter);
			}	
			
			return filterArray;		
		}

		/**
		 * @public
		 * Create an array of filters directly from the given styleName
		 */	
		public static function createFiltersManually(styleName:String, layerName:String="filterLayer"):Array{
			var filterStack:Array;
			var filterObject:Object;
			
			if(styleName.charAt(0)!=".")
				styleName="."+styleName;
			
			filterObject = StyleManager.getStyleDeclaration(styleName).getStyle(layerName);
			
			// Cast the filter objects to an array
			if(filterObject is String)
				filterStack=[filterObject];
			else
				filterStack=filterObject as Array;
			
			if(filterStack.length==0)
				return new Array();
			
			var filterArray:Array=[];
			for each(var filterStyleName:String in filterStack){
				// In case users forgot to put "." as a CSS class prefix, we are offering a adjustment here
				if(filterStyleName.charAt(0)!=".")
					filterStyleName="." + filterStyleName;
				
				var filter:BitmapFilter=parseFilter(filterStyleName);
				filterArray.push(filter);
			}	
			
			return filterArray;		
		}
		/**
		 * @public
		 * 
		 * Create a filter by "kind" and fill its propertites
		 */
		public static function parseFilter(filterStyleName:String):BitmapFilter{
			// First, we will find the CSS style, as defined in filterStyleName
			var filterStyle:CSSStyleDeclaration=StyleManager.getStyleDeclaration(filterStyleName);
			var filterClass:Class=filterStyle.getStyle("kind");
			var filter:BitmapFilter=new filterClass();
			
			// Then, we extract all properties defined in the CSS style:
			var styleFactory:* = new filterStyle.factory();
			for(var styleKey:* in styleFactory){
				// Ingnore "kind" propertity
				if(styleKey as String == "kind")
					continue;
				filter[styleKey] = styleFactory[styleKey];
			}
			
			return filter;
		}		
	}
}